using System;
using System.Collections.Generic;
using System.Text;

namespace TcKs.MSOffice.WrapperAssembliesCodeGenerator {
	/// <summary>
	/// Base class for VB.NET source code builders.
	/// </summary>
	/// <typeparam name="T_CODE_BUILDER">Final type of source code builder.</typeparam>
	public abstract class VbNetSourceCodeGeneratorBase<T_CODE_BUILDER> : SourceCodeBuilderBase<T_CODE_BUILDER> where T_CODE_BUILDER : VbNetSourceCodeGeneratorBase<T_CODE_BUILDER> {
		public VbNetSourceCodeGeneratorBase( System.IO.TextWriter writer ) : base( writer ) {
			this.Init();
		}
		public VbNetSourceCodeGeneratorBase( StringBuilder code ) : base( code ) {
			this.Init();
		}

		private void Init() {
			IEnumerable<string> arr_KeyWords = this.GetKeywords();
			if ( null != arr_KeyWords ) {
				this.Keywords.AddRange( arr_KeyWords );
			}
		}

		public List<string> keywords = new List<string>();
		public List<string> Keywords {
			get { return this.keywords; }
		}
		public IEnumerable<string> GetKeywords() {
			return new string[]{
				"AddHandler", "Alias", "Ansi", "As"
				, "Assembly", "Auto", "Binary", "ByRef"
				, "ByVal", "Case", "Catch", "Class"
				, "Custom", "Default", "DirectCast", "Each"
				, "Else", "ElseIf", "End", "Error"
				, "False", "Finally", "For", "Friend"
				, "Global", "Handles", "Implements", "In"
				, "Into", "Is", "Key", "Lib"
				, "Loop", "Me", "Module", "MustInherit"
				, "MustOverride", "MyBase", "MyClass", "Narrowing"
				, "New", "Next", "Nothing", "NotInheritable"
				, "NotOverridable", "Of", "Off", "On"
				, "Option", "Optional", "Overloads", "Overridable"
				, "Overrides", "ParamArray", "Partial", "Preserve"
				, "Private", "Protected", "Public", "RaiseEvent"
				, "ReadOnly", "RemoveHandler", "Resume", "Shadows"
				, "Shared", "Static", "Step", "Structure"
				, "Text", "Then", "To", "True"
				, "TryCast", "Unicode", "Until", "When"
				, "While", "Widening", "WithEvents", "WriteOnly"



				, "Object", "Select", "Operator", "Function"
				, "Sub", "Or", "And", "Namespace"
				, "Goto", "Date", "Char"
			};
		}
		protected override string NormalizeText( string text ) {
			string tmpText = base.NormalizeText( text );
			string ret = tmpText;

			IComparer<string> comparer = StringComparer.InvariantCultureIgnoreCase;
			foreach ( string str in this.Keywords ) {
				if ( 0 == comparer.Compare( str, ret ) ) {
					ret = "[" + ret + "]";
					break;
				}
			}

			return ret;
		}

		public T_CODE_BUILDER zZz() { return (T_CODE_BUILDER)this; }

		public T_CODE_BUILDER o { get { return this._( "." ); } }
		public T_CODE_BUILDER o_( string text ) { return this.o._( text ); }
		public T_CODE_BUILDER i { get { return this.Add( ", " ); } }
		public T_CODE_BUILDER i_( string text ) { return this.i._( text ); }

		public T_CODE_BUILDER __ { get { return this.Add( " " ); } }

		public T_CODE_BUILDER _E { get { return this.Add( " = " ); } }
		public T_CODE_BUILDER _E_( string text ) { return this._E._( text ); }
		public T_CODE_BUILDER _E_( Type type ) { return this._E._( type ); }
		public T_CODE_BUILDER _E_<T>() { return this._E._<T>(); }

		public T_CODE_BUILDER Me { get { return this.Add( "Me" ); } }
		public T_CODE_BUILDER Me_( string text ) { return this.Me.o._( text ); }
		public T_CODE_BUILDER MyBase { get { return this.Add( "MyBase" ); } }

		public T_CODE_BUILDER Dim { get { return this.Add( "Dim " ); } }
		public T_CODE_BUILDER Dim_( string text ) { return this.Dim._( text ); }

		public T_CODE_BUILDER Private { get { return this.Add( "Private " ); } }
		public T_CODE_BUILDER Friend { get { return this.Add( "Friend " ); } }
		public T_CODE_BUILDER Public { get { return this.Add( "Public " ); } }
		public T_CODE_BUILDER Protected { get { return this.Add( "Protected " ); } }

		public T_CODE_BUILDER MustInherit { get { return this.Add( "MustInherit " ); } }

		public T_CODE_BUILDER Class { get { return this.Add( "Class " ); } }
		public T_CODE_BUILDER Interface { get { return this.Add( "Interface " ); } }
		public T_CODE_BUILDER Enum { get { return this.Add( "Enum " ); } }
		public T_CODE_BUILDER Structure { get { return this.Add( "Structure " ); } }

		public T_CODE_BUILDER Get { get { return this.Add( "Get " ); } }
		public T_CODE_BUILDER Set { get { return this.Add( "Set " ); } }

		public T_CODE_BUILDER End { get { return this.Add( "End " ); } }

		public T_CODE_BUILDER Inherits { get { return this.Add( "Inherits " ); } }
		public T_CODE_BUILDER Inherits_( string text ) { return this.Inherits._( text ); }
		public T_CODE_BUILDER Inherits_( Type type ) { return this.Inherits._( type ); }
		public T_CODE_BUILDER Inherits_<T>() { return this.Inherits._<T>(); }

		public T_CODE_BUILDER Implements { get { return this.Add( "Implements " ); } }
		public T_CODE_BUILDER Implements_( string text ) { return this.Implements._( text ); }
		public T_CODE_BUILDER Implements_( Type type ) { return this.Implements._( type ); }
		public T_CODE_BUILDER Implements_<T>() { return this.Implements._<T>(); }

		public T_CODE_BUILDER Sub { get { return this.Add( "Sub " ); } }
		public T_CODE_BUILDER Function { get { return this.Add( "Function " ); } }
		public T_CODE_BUILDER Property { get { return this.Add( "Property " ); } }

		public T_CODE_BUILDER New { get { return this.Add( "New " ); } }
		public T_CODE_BUILDER New_( string text ) { return this.New._( text ); }
		public T_CODE_BUILDER New_( Type type ) { return this.New._( type ); }
		public T_CODE_BUILDER New_<T>() { return this.New._<T>(); }

		public T_CODE_BUILDER Overrides { get { return this.Add( "Overrides " ); } }

		public T_CODE_BUILDER ReadOnly { get { return this.Add( "ReadOnly " ); } }

		public T_CODE_BUILDER Shared { get { return this.Add( "Shared " ); } }

		public T_CODE_BUILDER ByVal { get { return this.Add( "ByVal " ); } }
		public T_CODE_BUILDER ByVal_( string text ) { return this.ByVal._( text ); }
		public T_CODE_BUILDER ByRef { get { return this.Add( "ByRef " ); } }
		public T_CODE_BUILDER ByRef_( string text ) { return this.ByRef._( text ); }

		public T_CODE_BUILDER As { get { return this.Add( "As " ); } }
		public T_CODE_BUILDER _As { get { return this.__.As.zZz(); } }

		public T_CODE_BUILDER As_( string text ) { return this.As._( text ); }
		public T_CODE_BUILDER As_( Type type ) { return this.As._( type ); }
		public T_CODE_BUILDER As_<T>() { return this.As._<T>(); }
		public T_CODE_BUILDER _As_( string text ) { return this._As._( text ); }
		public T_CODE_BUILDER _As_( Type type ) { return this._As._( type ); }
		public T_CODE_BUILDER _As_<T>() { return this._As._<T>(); }

		public T_CODE_BUILDER Return { get { return this.Add( "Return " ); } }
		public T_CODE_BUILDER Return_( string text ) { return this.Return._( text ); }
		public T_CODE_BUILDER Value { get { return this.Add( "Value " ); } }

		public T_CODE_BUILDER _V { get { return this.Add( "( " ); } }
		public T_CODE_BUILDER V_ { get { return this.Add( " )" ); } }
		public T_CODE_BUILDER _VV_ { get { return this.Add( "()" ); } }

		public T_CODE_BUILDER If { get { return this.Add( "If " ); } }
		public T_CODE_BUILDER If_( string text ) { return this.If._( text ); }
		public T_CODE_BUILDER ElseIf { get { return this.Add( "ElseIf " ); } }
		public T_CODE_BUILDER ElseIf_( string text ) { return this.ElseIf._( text ); }
		public T_CODE_BUILDER Else { get { return this.Add( "Else " ); } }
		public T_CODE_BUILDER Then { get { return this.Add( "Then " ); } }

		public T_CODE_BUILDER Is { get { return this.Add( "Is " ); } }
		public T_CODE_BUILDER Is_( string text ) { return this.Is._( text ); }
		public T_CODE_BUILDER Is_<T>() { return this.Is._<T>(); }
		public T_CODE_BUILDER IsNot { get { return this.Add( "IsNot " ); } }
		public T_CODE_BUILDER IsNot_( string text ) { return this.Is._( text ); }
		public T_CODE_BUILDER IsNot_<T>() { return this.Is._<T>(); }
		public T_CODE_BUILDER Nothing { get { return this.Add( "Nothing " ); } }
		public T_CODE_BUILDER IsNothing { get { return this.Is.Nothing; } }
		public T_CODE_BUILDER IsNotNothing { get { return this.IsNot.Nothing; } }

		public T_CODE_BUILDER Or { get { return this.Add( "Or " ); } }
		public T_CODE_BUILDER Or_( string text ) { return this.Or._( text ); }
		public T_CODE_BUILDER And { get { return this.Add( "And " ); } }
		public T_CODE_BUILDER And_( string text ) { return this.And._( text ); }
		public T_CODE_BUILDER Not { get { return this.Add( "Not " ); } }
		public T_CODE_BUILDER Not_( string text ) { return this.Not._( text ); }

		public T_CODE_BUILDER TypeOf { get { return this.Add( "TypeOf " ); } }
		public T_CODE_BUILDER TypeOf_( string text ) { return this.TypeOf._( text ); }
	}

	/// <summary>
	/// Final class of VB.NET source code builder.
	/// </summary>
	public sealed class VbNetSourceCodeGenerator : VbNetSourceCodeGeneratorBase<VbNetSourceCodeGenerator> {
		public VbNetSourceCodeGenerator( System.IO.TextWriter writer ) : base( writer ) { }
		public VbNetSourceCodeGenerator( StringBuilder code ) : base( code ) { }
	}
}
